package cn.com.xf.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import cn.com.xf.dao.TblCheckDataDAO;
import cn.com.xf.dao.TblCheckHolidayDAO;
import cn.com.xf.dao.TblCheckLeaveDAO;
import cn.com.xf.dao.TblCheckMendDAO;
import cn.com.xf.dao.TblCheckReportDAO;
import cn.com.xf.dao.TblCheckScheduleDAO;
import cn.com.xf.dao.TblCheckShiftDAO;
import cn.com.xf.dao.TsUserDAO;
import cn.com.xf.domain.TblCheckData;
import cn.com.xf.domain.TblCheckHoliday;
import cn.com.xf.domain.TblCheckLeave;
import cn.com.xf.domain.TblCheckMend;
import cn.com.xf.domain.TblCheckReport;
import cn.com.xf.domain.TblCheckSchedule;
import cn.com.xf.domain.TblCheckShift;
import cn.com.xf.domain.TsUser;
import cn.com.xf.service.AnalyzeService;
import cn.com.xf.task.AnalyzeTask;
import cn.com.xf.utils.DateUtils;
/**
 * 考勤分析
 *
 */
@Service("analyzeService")
public class AnalyzeServiceImpl implements AnalyzeService {

	@Autowired
	private TblCheckScheduleDAO scheduleDAO;
	@Autowired
	private TblCheckShiftDAO shiftDAO;
	@Autowired
	private TblCheckMendDAO mendDAO;
	@Autowired
	private TblCheckLeaveDAO leaveDAO;
	@Autowired
	private TblCheckDataDAO checkDataDAO;
	@Autowired
	private TsUserDAO userDAO;
	@Autowired
	private TblCheckHolidayDAO holidayDAO;
	@Autowired
	private TblCheckReportDAO reportDAO;

	@Autowired
	private ThreadPoolTaskExecutor taskExecutor;
	
	@Override
	public void analyze(String siteid, String deptid, String userid,
			Date startDate, Date endDate) throws Exception {
		System.out.println("---analyzeService----");
		if (!userid.equals("")) {
			if (userid.contains(",")) {
				String[] userids = userid.split(",");
				for (String u: userids) {
					analyzeUser(u, startDate, endDate);
					
				}
			} else {
				analyzeUser(userid, startDate, endDate);
			}
		} else if (!deptid.equals("") && !siteid.equals("")) { 
			List<TsUser> userList = userDAO.selectUserBySiteIdAndDeptid(siteid, deptid);
			for (TsUser user : userList) {
				analyzeUser(user.getUserid(), startDate, endDate);
			}
			
		} 
		

	}

	private void analyzeUser(String userid, Date startDate, Date endDate) throws Exception {
		List<TblCheckSchedule> scheduleList = scheduleDAO.selectScheduleByUserid(userid);
		Calendar calendar = Calendar.getInstance();
		Date curDate = startDate;
		// 遍历日期范围
		while (curDate.compareTo(endDate) <= 0) {
			double shouldHours = 0;
			double realHours = 0;
			double offworkHours = 0;
			double leaveHours = 0;
			int latenum = 0; //迟到次数
			int earlynum = 0; //早退次数
			double offworknum = 0; //旷工天数
			double leavenum = 0;
			double holidaynum = 0;
			long fLateMin = 0;
			long sLateMin = 0;
			long tLateMin = 0;
			long fEarlyMin = 0;
			long sEarlyMin = 0;
			long tEarlyMin = 0;
			Date fCheckin = null;
			Date sCheckin = null;
			Date tCheckin = null;
			Date fCheckout = null;
			Date sCheckout = null;
			Date tCheckout = null;
			calendar.setTime(curDate);
			boolean isScheduled = false;
			String day = calendar.get(Calendar.DAY_OF_WEEK) - 1 + "";
			// 查询当天补卡信息
			List<TblCheckMend> mendList = mendDAO.selectMendByUseridAndCheckdate(userid, curDate);
			// 查询当天考勤数据
			List<TblCheckData> checkDataList = checkDataDAO.selectCheckDataByUseridAndDate(userid, curDate);							
			// 查询员工请假
			List<TblCheckLeave> leaveList = leaveDAO.selectLeaveByUserid(userid);
			List<TblCheckHoliday> holidayList = holidayDAO.selectBySiteid(userid.substring(0, 6));
			// 把补卡信息加入到考勤数据列表
			if (mendList.size() > 0) {
				for (TblCheckMend mend: mendList) {
					// 上班卡
					if (mend.getType() == 0) {
						if (mend.getTime1() != null) {
							TblCheckData checkData = new TblCheckData();
							checkData.setCheckdate(curDate);
							checkData.setChecktime(mend.getTime1());
							checkData.setType((short) 0);
							checkDataList.add(checkData);
						}
						if (mend.getTime2() != null) {
							TblCheckData checkData = new TblCheckData();
							checkData.setCheckdate(curDate);
							checkData.setChecktime(mend.getTime2());
							checkData.setType((short) 0);
							checkDataList.add(checkData);
						}	
						if (mend.getTime3() != null) {
							TblCheckData checkData = new TblCheckData();
							checkData.setCheckdate(curDate);
							checkData.setChecktime(mend.getTime3());
							checkData.setType((short) 0);
							checkDataList.add(checkData);
						}							
					}
					// 下班卡
					if (mend.getType() == 1) {
						if (mend.getTime1() != null) {
							TblCheckData checkData = new TblCheckData();
							checkData.setCheckdate(curDate);
							checkData.setChecktime(mend.getTime1());
							checkData.setType((short) 1);
							checkDataList.add(checkData);
						}
						if (mend.getTime2() != null) {
							TblCheckData checkData = new TblCheckData();
							checkData.setCheckdate(curDate);
							checkData.setChecktime(mend.getTime2());
							checkData.setType((short) 1);
							checkDataList.add(checkData);
						}	
						if (mend.getTime3() != null) {
							TblCheckData checkData = new TblCheckData();
							checkData.setCheckdate(curDate);
							checkData.setChecktime(mend.getTime3());
							checkData.setType((short) 1);
							checkDataList.add(checkData);
						}							
					}							
				}
			}	
			for (TblCheckSchedule schedule : scheduleList) {
				// 判断当前日期在排班日期范围内
				if (schedule.getStartdate().compareTo(curDate) <= 0
						&& schedule.getEnddate().compareTo(curDate) >= 0) {
					isScheduled = true;
					// 查询班次信息
					TblCheckShift shift = shiftDAO.selectShiftById(schedule.getShiftid());
					// 当天的班次签到签退时间
					Date fCheckintime=null,fCheckouttime=null,sCheckintime=null,sCheckouttime=null,tCheckintime=null,tCheckouttime=null;
					if (shift.getfCheckintime()!=null&&!shift.getfCheckintime().equals(":"))
						fCheckintime = DateUtils.connectDateAndTime(curDate, shift.getfCheckintime());
					if (shift.getfCheckouttime()!=null&&!shift.getfCheckouttime().equals(":"))
						fCheckouttime = DateUtils.connectDateAndTime(curDate, shift.getfCheckouttime());
					if (shift.getsCheckintime()!=null&&!shift.getsCheckintime().equals(":"))
						sCheckintime = DateUtils.connectDateAndTime(curDate, shift.getsCheckintime());
					if (shift.getsCheckouttime()!=null&&!shift.getsCheckouttime().equals(":"))
						sCheckouttime = DateUtils.connectDateAndTime(curDate, shift.getsCheckouttime());
					if (shift.gettCheckintime()!=null&&!shift.gettCheckintime().equals(":"))
						tCheckintime = DateUtils.connectDateAndTime(curDate, shift.gettCheckintime());
					if (shift.gettCheckouttime()!=null&&!shift.gettCheckouttime().equals(":"))
						tCheckouttime = DateUtils.connectDateAndTime(curDate, shift.gettCheckouttime());					
					// 第一个时间段计算迟到，而且是工作日
					if (shift.getfAsLate()!=null && shift.getfAsLate().trim().equals("1")) {
						boolean hasData = false;
						boolean isLeave = false;
						boolean isHoliday = false;
						for (TblCheckLeave leave: leaveList) {
							if (leave.getStartdate().compareTo(fCheckintime) <= 0 && leave.getEnddate().compareTo(fCheckintime) >= 0) {
								isLeave = true;
							}
						}
						for (TblCheckHoliday holiday: holidayList) {
							if (holiday.getStartdate().compareTo(fCheckintime) <= 0 && holiday.getEnddate().compareTo(fCheckintime) >= 0) {
								isHoliday = true;
							}
						}
						if (!isHoliday && shift.getfWorkDay().contains(day)) {
							shouldHours = shouldHours + DateUtils.getHour(fCheckintime, fCheckouttime);
							List<Date> allChecktime = new ArrayList<Date>();
							for (TblCheckData checkData: checkDataList) {
								if (checkData.getType() == 0) {
									if (checkData.getChecktime().compareTo(fCheckouttime) < 0) {
										hasData =  true;
										allChecktime.add(checkData.getChecktime());
										
									} 
								}
							}

							if (!hasData) {
								// 旷工
								if (!isLeave) {
									offworknum = offworknum + Double.parseDouble(shift.getfCheckedDays());
									offworkHours += DateUtils.getHour(fCheckintime, fCheckouttime);
								} else {
									leavenum = leavenum + Double.parseDouble(shift.getfCheckedDays());
									leaveHours = leaveHours + DateUtils.getHour(fCheckintime, fCheckouttime);									
								}
							} else {
								fCheckin = DateUtils.getFirstDate(allChecktime);
								Calendar ca = Calendar.getInstance();
								ca.setTime(fCheckintime);
								// 当天班次上班时间加上设置的迟到分钟数
								ca.add(Calendar.MINUTE, shift.getfLaterMinute());
								if (fCheckin.compareTo(ca.getTime()) > 0) {
									//迟到
									latenum++;
									//迟到分钟数
									fLateMin = (fCheckin.getTime() - ca.getTimeInMillis()) / (1000 * 60);
								}								
							}
						} else {
							if (isHoliday)
								holidaynum = holidaynum + Double.parseDouble(shift.getfCheckedDays());
						}
					}
					
					if (shift.getfAsEarly()!=null && shift.getfAsEarly().trim().equals("1")) {
						boolean hasData = false;
						boolean isLeave = false;
						boolean isHoliday = false;
						for (TblCheckLeave leave: leaveList) {
							if (leave.getStartdate().compareTo(fCheckouttime) <= 0 && leave.getEnddate().compareTo(fCheckouttime) >= 0) {
								isLeave = true;
							}
						}
						for (TblCheckHoliday holiday: holidayList) {
							if (holiday.getStartdate().compareTo(fCheckouttime) <= 0 && holiday.getEnddate().compareTo(fCheckouttime) >= 0) {
								isHoliday = true;
							}
						}
						if (!isHoliday && shift.getfWorkDay().contains(day)) {
							List<Date> allChecktime = new ArrayList<Date>();
							for (TblCheckData checkData: checkDataList) {
								if (checkData.getType() == 1) {
									if (checkData.getChecktime().compareTo(sCheckintime) < 0) {
										hasData = true;
										allChecktime.add(checkData.getChecktime());

									}
								}
							}
							if (!hasData) {
								if (!isLeave) {
									earlynum++;
								}							
							} else {	
								fCheckout = DateUtils.getLastDate(allChecktime);
								Calendar ca = Calendar.getInstance();
								ca.setTime(fCheckouttime);
								// 当天班次下班时间减去设置的早退分钟数
								ca.add(Calendar.MINUTE, -1*shift.getfEarlierMinute());
								if (fCheckout.compareTo(ca.getTime()) < 0) {
									//早退
									earlynum++;
									fEarlyMin = (ca.getTimeInMillis() - fCheckout.getTime()) / (1000 * 60);
								}
							}
						}
						
					}
					
					if (shift.getsAsLate()!=null && shift.getsAsLate().trim().equals("1")) {
						boolean hasData = false;
						boolean isLeave = false;
						boolean isHoliday = false;
						for (TblCheckLeave leave: leaveList) {
							if (leave.getStartdate().compareTo(sCheckintime) <= 0 && leave.getEnddate().compareTo(sCheckintime) >= 0) {
								isLeave = true;
							}
						}
						for (TblCheckHoliday holiday: holidayList) {
							if (holiday.getStartdate().compareTo(sCheckintime) <= 0 && holiday.getEnddate().compareTo(sCheckintime) >= 0) {
								isHoliday = true;
							}
						}
						if (!isHoliday && shift.getsWorkDay().contains(day)) {
							shouldHours = shouldHours + DateUtils.getHour(sCheckintime, sCheckouttime);
							List<Date> allChecktime = new ArrayList<Date>();
							for (TblCheckData checkData: checkDataList) {
								if (checkData.getType() == 0) {
									if (checkData.getChecktime().compareTo(fCheckouttime) > 0 && checkData.getChecktime().compareTo(sCheckouttime) < 0) {
										hasData = true;
										allChecktime.add(checkData.getChecktime());
								
									} 
								}
							}
							
							if (!hasData) {
								if (!isLeave) {
									// 旷工
									offworknum = offworknum + Double.parseDouble(shift.getsCheckedDays());
									offworkHours += DateUtils.getHour(sCheckintime, sCheckouttime);
								} else {
									leavenum = leavenum + Double.parseDouble(shift.getsCheckedDays());
									leaveHours = leaveHours + DateUtils.getHour(sCheckintime, sCheckouttime);
								}
							} else {						
								sCheckin = DateUtils.getFirstDate(allChecktime);
								Calendar ca = Calendar.getInstance();
								ca.setTime(sCheckintime);
								// 当天班次上班时间加上设置的迟到分钟数
								ca.add(Calendar.MINUTE, shift.getsLaterMinute());
								if (sCheckin.compareTo(ca.getTime()) > 0) {
									//迟到
									latenum++;
									sLateMin = (sCheckin.getTime() - ca.getTimeInMillis()) / (1000 * 60);
								}		
							}
						} else {
							if (isHoliday)
								holidaynum = holidaynum + Double.parseDouble(shift.getsCheckedDays());
						}
					}
					
					if (shift.getsAsEarly()!=null && shift.getsAsEarly().trim().equals("1")) {
						boolean hasData = false;
						boolean isLeave = false;
						boolean isHoliday = false;
						for (TblCheckLeave leave: leaveList) {
							if (leave.getStartdate().compareTo(sCheckouttime) <= 0 && leave.getEnddate().compareTo(sCheckouttime) >= 0) {
								isLeave = true;
							}
						}
						for (TblCheckHoliday holiday: holidayList) {
							if (holiday.getStartdate().compareTo(sCheckouttime) <= 0 && holiday.getEnddate().compareTo(sCheckouttime) >= 0) {
								isHoliday = true;
							}
						}
						if (!isHoliday && shift.getsWorkDay().contains(day)) {
							List<Date> allChecktime = new ArrayList<Date>();
							for (TblCheckData checkData: checkDataList) {
								if (checkData.getType() == 1) {
									if (checkData.getChecktime().compareTo(sCheckintime) > 0) {
										hasData = true;
										allChecktime.add(checkData.getChecktime());
									
									}
								}
							}
							
							if (!hasData) {
								if (!isLeave) {
									earlynum++;
								}							
							} else {
								sCheckout = DateUtils.getLastDate(allChecktime);
								Calendar ca = Calendar.getInstance();
								ca.setTime(sCheckouttime);
								// 当天班次下班时间减去设置的早退分钟数
								ca.add(Calendar.MINUTE, -1*shift.getsEarlierMinute());
								if (sCheckout.compareTo(ca.getTime()) < 0) {
									//早退
									earlynum++;
									sEarlyMin = (ca.getTimeInMillis() - sCheckout.getTime()) / (1000 * 60);
								}	
							}
						}
					}
					
					if (shift.gettAsLate()!=null && shift.gettAsLate().trim().equals("1")) {
						boolean hasData = false;
						boolean isLeave = false;
						boolean isHoliday = false;
						for (TblCheckLeave leave: leaveList) {
							if (leave.getStartdate().compareTo(tCheckintime) <= 0 && leave.getEnddate().compareTo(tCheckintime) >= 0) {
								isLeave = true;
							}
						}
						for (TblCheckHoliday holiday: holidayList) {
							if (holiday.getStartdate().compareTo(tCheckintime) <= 0 && holiday.getEnddate().compareTo(tCheckintime) >= 0) {
								isHoliday = true;
							}
						}
						if (!isHoliday && shift.gettWorkDay().contains(day)) {
							shouldHours = shouldHours + DateUtils.getHour(sCheckintime, sCheckouttime);
							List<Date> allChecktime = new ArrayList<Date>();
							for (TblCheckData checkData: checkDataList) {
								if (checkData.getType() == 0) {
									if (checkData.getChecktime().compareTo(sCheckouttime) > 0 && checkData.getChecktime().compareTo(tCheckouttime) < 0) {
										hasData = true;
										allChecktime.add(checkData.getChecktime());
									
									} 
								}
							}
							if (!hasData) {
								if (!isLeave) {
									// 旷工
									offworknum = offworknum + Double.parseDouble(shift.gettCheckedDays());
									offworkHours += DateUtils.getHour(tCheckintime, tCheckouttime);
								} else {
									leavenum = leavenum + Double.parseDouble(shift.gettCheckedDays());
									leaveHours = leaveHours + DateUtils.getHour(tCheckintime, tCheckouttime);
								}
							} else {
								tCheckin = DateUtils.getFirstDate(allChecktime);
								Calendar ca = Calendar.getInstance();
								ca.setTime(tCheckintime);
								// 当天班次上班时间加上设置的迟到分钟数
								ca.add(Calendar.MINUTE, shift.gettLaterMinute());
								if (tCheckin.compareTo(ca.getTime()) > 0) {
									//迟到
									latenum++;
									tLateMin = (tCheckin.getTime() - ca.getTimeInMillis()) / (1000 * 60);
								}	
							}
						} else {
							if (isHoliday)
								holidaynum = holidaynum + Double.parseDouble(shift.gettCheckedDays());
						}
					}					
					
					if (shift.gettAsEarly()!=null && shift.gettAsEarly().trim().equals("1")) {
						boolean hasData = false;
						boolean isLeave = false;
						boolean isHoliday = false;
						for (TblCheckLeave leave: leaveList) {
							if (leave.getStartdate().compareTo(tCheckouttime) <= 0 && leave.getEnddate().compareTo(tCheckouttime) >= 0) {
								isLeave = true;
							}
						}
						for (TblCheckHoliday holiday: holidayList) {
							if (holiday.getStartdate().compareTo(tCheckouttime) <= 0 && holiday.getEnddate().compareTo(tCheckouttime) >= 0) {
								isHoliday = true;
							}
						}
						if (!isHoliday && shift.gettWorkDay().contains(day)) {
							List<Date> allChecktime = new ArrayList<Date>();
							for (TblCheckData checkData: checkDataList) {
								if (checkData.getType() == 1) {
									if (checkData.getChecktime().compareTo(tCheckintime) > 0) {
										hasData = true;
										allChecktime.add(checkData.getChecktime());
									
									}
								}
							}
							
							if (!hasData) {
								if (!isLeave) {
									earlynum++;
								}							
							} else {
								tCheckout = DateUtils.getLastDate(allChecktime);
								Calendar ca = Calendar.getInstance();
								ca.setTime(tCheckouttime);
								// 当天班次下班时间减去设置的早退分钟数
								ca.add(Calendar.MINUTE, -1*shift.gettEarlierMinute());
								if (tCheckout.compareTo(ca.getTime()) < 0) {
									//早退
									earlynum++;
									tEarlyMin = (ca.getTimeInMillis() - tCheckout.getTime()) / (1000 * 60);
								}	
							}
						}
					}					
					
					
				} else {
					// 当前日期不在排班表
					isScheduled = false;
				}
			}
			if (isScheduled) {
				// 计算实际出勤小时数
				long allLateMin = fLateMin + sLateMin + tLateMin;
				long allEarlyMin = fEarlyMin + sEarlyMin + tEarlyMin;
				realHours = shouldHours - allLateMin / 60.0 - allEarlyMin / 60.0 - offworkHours - leaveHours;
				TblCheckReport report = reportDAO.selectByUseridAndCheckdate(userid, curDate);
				if (report != null) {
					report.setShouldHours(shouldHours);
					report.setRealHours(realHours);
					report.setEarlynum(earlynum);
					report.setHolidaynum(holidaynum);
					report.setLatenum(latenum);
					report.setLeavenum(leavenum);
					report.setOffworknum(offworknum);
					report.setfLateMin(fLateMin);
					report.setsLateMin(sLateMin);
					report.settLateMin(tLateMin);
					report.setfEarlyMin(fEarlyMin);
					report.setsEarlyMin(sEarlyMin);
					report.settEarlyMin(tEarlyMin);
					report.setfCheckintime(fCheckin);
					report.setsCheckintime(sCheckin);
					report.settCheckintime(tCheckin);
					report.setfCheckouttime(fCheckout);
					report.setsCheckouttime(sCheckout);
					report.settCheckouttime(tCheckout);
					report.setSiteid(userid.substring(0, 6));
					reportDAO.updateByPrimaryKey(report);
				} else {
					report = new TblCheckReport();
					report.setUserid(userid);
					report.setCheckdate(curDate);
					report.setShouldHours(shouldHours);
					report.setRealHours(realHours);
					report.setEarlynum(earlynum);
					report.setHolidaynum(holidaynum);
					report.setLatenum(latenum);
					report.setLeavenum(leavenum);
					report.setOffworknum(offworknum);
					report.setfLateMin(fLateMin);
					report.setsLateMin(sLateMin);
					report.settLateMin(tLateMin);
					report.setfEarlyMin(fEarlyMin);
					report.setsEarlyMin(sEarlyMin);
					report.settEarlyMin(tEarlyMin);
					report.setfCheckintime(fCheckin);
					report.setsCheckintime(sCheckin);
					report.settCheckintime(tCheckin);
					report.setfCheckouttime(fCheckout);
					report.setsCheckouttime(sCheckout);
					report.settCheckouttime(tCheckout);
					report.setSiteid(userid.substring(0, 6));
					reportDAO.insert(report);
				}
			}
			calendar.add(Calendar.DATE, 1);
			curDate = calendar.getTime();
		}
	}
}
